home *** CD-ROM | disk | FTP | other *** search
- # include "ctlmod.h"
- # include <ingres.h>
- # include <aux.h>
- # include <tree.h>
- # include <symbol.h>
- # include <sccs.h>
- # include <errors.h>
-
- SCCSID(@(#)readqry.c 8.3 12/8/85)
-
-
- /*
- ** READQRY
- **
- ** Reads in query symbols from input pipe into core
- ** locations and sets up information needed for later
- ** processing.
- **
- ** Returns ptr to root of querytree
- **
- ** Locbuf is a 'struct srcid' since that is the largest node of
- ** a QMODE, SOURCEID, or RESULTVAR node.
- */
-
- QTREE *
- readqry(rdfn, fnparam, initialize)
- int (*rdfn)(); /* tree read function */
- int fnparam; /* parameter to pass to rdfn */
- bool initialize; /* if set, initialize Qbuf */
- {
- register QTREE *q;
- register QTREE *rtval;
- register DESC *d;
- extern QTREE *readtree();
- extern char *xalloc();
- extern QTREE *trbuild();
- int mark;
- extern QTREE *readsym();
- int i;
- int j;
-
- # ifdef xCTR1
- if (tTf(10, 8))
- printf("READQRY:\n");
- # endif
-
- if (initialize)
- {
- /* initialize for new query block */
- clrrange();
- Qt.qt_resvar = -1;
- Qt.qt_qmode = -1;
- }
- for (i = 0; i < MAXRANGE; i++)
- Qt.qt_remap[i] = i;
-
- mark = markbuf(Qbuf);
-
- /* read symbols from input */
- for (;;)
- {
- freebuf(Qbuf, mark);
- q = readsym(rdfn, fnparam);
- switch (q->sym.type)
- {
- case QMODE:
- if (Qt.qt_qmode != -1)
- syserr("readqry: two qmodes");
- Qt.qt_qmode = q->sym.value.sym_data.i2type;
- break;
-
- case RESULTVAR:
- if (Qt.qt_resvar != -1)
- syserr("readqry: two resultvars");
- Qt.qt_resvar = q->sym.value.sym_data.i2type;
- break;
-
- case SOURCEID:
- d = (DESC *) xalloc(sizeof *d);
- bmove((char *) &q->sym.value.sym_srcid.srcdesc, (char *) d, sizeof *d);
- i = q->sym.value.sym_srcid.srcvar;
- j = declare(i, d);
- if (j != i && initialize)
- syserr("readqry: declare(%d)=%d", i, j);
- Qt.qt_remap[i] = j;
- break;
-
- case TREE: /* beginning of tree, no more other stuff */
- q = readtree(q, rdfn, fnparam);
- rtval = trbuild(q);
- if (rtval == NULL)
- error(STACKFULL, 0);
- return (rtval);
-
- default:
- syserr("readqry: bad symbol %d", q->sym.type);
- }
- }
- }
- /*
- ** READSYM
- ** reads in one symbol from pipe into symbol struct.
- */
-
- QTREE *
- readsym(rdfn, fnparam)
- int (*rdfn)(); /* tree read function */
- char *fnparam;
- {
- register int len;
- register int t;
- register QTREE *q;
- extern char *need();
- int rlen;
-
- q = (QTREE *) need(Qbuf, QT_HDR_SIZ);
- if ((*rdfn)(fnparam, &q->sym, TYP_LEN_SIZ) < TYP_LEN_SIZ)
- syserr("readsym: read sym");
- rlen = len = q->sym.len & I1MASK;
- t = q->sym.type;
-
- switch (t)
- {
- case AND:
- if (len < 6)
- len = 6;
- break;
-
- case ROOT:
- case AGHEAD:
- if (len < 8)
- len = 8;
- break;
- }
-
- q->sym.len = len;
-
-
- if (len != 0)
- {
- /* this will be contiguous with above need call */
- need(Qbuf, len);
- }
- if (rlen != 0)
- {
- if ((*rdfn)(fnparam, &q->sym.value, rlen) < rlen)
- syserr("readsym: read val (sym=%d,%d)", t, rlen);
- }
-
- switch (t)
- {
- case ROOT:
- q->sym.value.sym_root.rootuser = TRUE;
- break;
- case AGHEAD:
- q->sym.value.sym_root.rootuser = FALSE;
- break;
- }
- # ifdef xCTR1
- if (tTf(10, 9))
- nodepr(q);
- # endif xCTR1
-
- return (q);
- }
- /*
- ** READTREE
- **
- ** reads in tree symbols into a buffer up to a root (end) symbol
- **
- */
-
- QTREE *
- readtree(tresym, rdfn, fnparam)
- QTREE *tresym;
- int (*rdfn)();
- char *fnparam;
- {
- register QTREE *q;
- register QTREE *rtval;
- extern char *need();
-
- rtval = tresym;
-
- for(;;)
- {
- /* space for left & right pointers */
- q = readsym(rdfn, fnparam);
- if (q->sym.type == ROOT)
- return (rtval);
- }
- }
- /*
- ** TRBUILD -- Rebuild a tree in memory
- **
- ** Trbuild is called with a pointer to the TREE node of
- ** a query already in memory. It rebuilds the pointer
- ** structure assuming the querytree is in postfix order.
- **
- ** Parameters:
- ** bufptr - a pointer to the TREE node
- **
- ** Returns:
- ** NULL - Internal stack overflow (STACKSIZ)
- ** pointer to the ROOT node
- **
- ** Side Effects:
- ** All left & right pointers are rebuilt.
- **
- ** Called By:
- ** readqry
- **
- ** Syserrs:
- ** syserr if there are too many leaf nodes or too
- ** few child nodes
- */
-
-
- QTREE *
- trbuild(bufptr)
- QTREE *bufptr;
- {
- register QTREE **stackptr;
- register char *p;
- register SYMBOL *s;
- QTREE *treestack[STACKSIZ];
- extern bool leaf();
-
-
- stackptr = treestack;
-
- /*XXX*/ for (p = (char *) bufptr;; p += QT_HDR_SIZ + ((s->len + 3) & 0374))
- {
- s = &((QTREE *)p)->sym;
- ((QTREE *)p)->left = ((QTREE *)p)->right = 0;
-
- /* reunite p with left and right children on stack, if any*/
- if (!leaf((QTREE *) p)) /* this node has children */
- {
- if (s->type != UOP)
- if (stackptr <= treestack)
- {
- err:
- syserr("trbuild:too few nodes");
- }
- else
- ((QTREE *)p)->right = *(--stackptr);
- if (s->type != AOP)
- if (stackptr <= treestack)
- goto err;
- else
- ((QTREE *)p)->left = *(--stackptr);
- }
-
- /*
- ** If this is a ROOT node then the tree is complete.
- ** verify that there are no extra nodes in the
- ** treestack.
- */
- if (s->type == ROOT) /* root node */
- {
- if (stackptr != treestack)
- syserr("trbuild:xtra nodes");
- return ((QTREE *)p);
- }
-
- /* stack p */
- if (stackptr-treestack >= STACKSIZ)
- return (NULL); /* error:stack full */
- *(stackptr++) = (QTREE *) p;
-
- }
- }
-
-
- bool
- leaf(p)
- QTREE *p;
- {
- switch (p->sym.type)
- {
- case VAR:
- case TREE:
- case QLEND:
- case INT:
- case FLOAT:
- case CHAR:
- case COP:
- return(TRUE);
-
- default:
- return(FALSE);
- }
- }
-